#include <stdio.h>
//#include <stdlib.h>  //中文显示乱码引入此头文件,使用函数system("chcp 65001");
#include <stdbool.h>
#include <string.h>
#include "test.h"


//测试 float 类型与仓颉跨语言的数据类型匹配
__declspec(dllexport) float floatAdd(float x, float y) {
    double d = x + y;
    return d;
}
//测试 double 类型与仓颉跨语言的数据类型匹配
__declspec(dllexport) double doubleAdd(double x, double y) {
    double d = x + y;
    return d;
}
//测试 int 类型与仓颉跨语言的数据类型匹配 
__declspec(dllexport) int intAdd (int x,int y){
    return x+y;
}
//测试 char 类型与仓颉跨语言的数据类型匹配
__declspec(dllexport) char charAdd (char x){
    return x+1;
}
//测试 short 类型与仓颉跨语言的数据类型匹配
__declspec(dllexport) short shortAdd (short x,short y){
    return x+y;
}
//测试 long 类型与仓颉跨语言的数据类型匹配
__declspec(dllexport) long longAdd (long x,long y){
    return x+y;
}
//测试 long long 类型与仓颉跨语言的数据类型匹配
__declspec(dllexport) long long longlongAdd (long long x,long long y){
    return x+y;
}
//测试 bool 类型与仓颉跨语言的数据类型匹配
__declspec(dllexport) bool boolNot ( bool x){
    return !x;
}
//测试c语言不同数据类型的大小
 __declspec(dllexport) void printSize(){
    char c='A';
    short s=127;
    int i= 0;
    long l=0;
    long long ll=0;
    float f=0.0;
    double d=0.0;
    bool b=0;
    //system("chcp 65001");  //解决中文显示乱码问题
    printf("\n**********开始打印**********\n");
    printf("char\t\tc=%c,\tsize=%2lld\n",c,sizeof(c));
    printf("short\t\ts=%d,\tsize=%2lld\n",s,sizeof(s));
    printf("int\t\ti=%d,\tsize=%2lld\n",i,sizeof(i));
    printf("long\t\tl=%ld,\tsize=%2lld\n",l,sizeof(l));
    printf("long long\tll=%lld,\tsize=%2lld\n",ll,sizeof(ll));
    
    printf("float\t\tf=%0.2f,\tsize=%2lld\n",f,sizeof(f));
    printf("double\t\td=%0.2f,\tsize=%2lld\n",d,sizeof(d));

    printf("bool\t\tb=%d,\tsize=%2lld\n",b,sizeof(b));
    printf("**********打印结束**********\n\n");
}

/*
char			//字符数据类型
short  			//短整型
int				//整形
long			//长整型
long long  		//更长的整形
float			//单精度浮点数
double 			//双精度浮点数
*/

//测试c语言结构体与仓颉结构体的跨语言操作
 typedef struct {
    long long x;
    long long y;
    long long z;
} Point3D;
//测试c语言结构体与仓颉结构体的跨语言操作
__declspec(dllexport)  Point3D addPoint(Point3D p1, Point3D p2){
    Point3D p3;
    p3.x=p1.x+p2.x;
    p3.y=p1.y+p2.y;
    p3.z=p1.z+p2.z;
    return p3;
}
//测试C语言void指针转成intptr_t的使用,打印地址查看地址有无变化
__declspec(dllexport) intptr_t voidToIntptr_t(void *data)
{
    printf("** 这里是C语言 voidToIntptr_t \n");
    printf("参数\tdata\t地址\t= %p\n",data);
    intptr_t p=(intptr_t)data;
    int* p1=(int *)p; 
    *p1+=10;
    printf("参数\tp\t地址\t= %016llX \n", p);
    printf("参数\tp\t地址\t= %p\n",p1);
    printf("参数\tp\t值\t= %d\n",*p1);
    printf("** 结束 voidToIntptr_t \n");
    return p;
}
//测试C语言void指针转成 int 指针的使用
__declspec(dllexport) int* voidToInt(void *data)
{
    int* p=(int *)data; 
    printf("参数\tp\t值\t= %d\n",*p);
    *p+=10;
    printf("参数\tp\t值\t= %d\n",*p);
    return p;
}
//测试C语言void指针转成 char 指针的使用
__declspec(dllexport) char * voidToString(void *data)
{
    char* p=(char *)data; 
    printf("参数\tp1\t值\t= %c\n",*p);
    *p+=10;
    printf("参数\tp1\t值\t= %c\n",*p);
    return p;
}
//测试C语言void指针转成 float 指针的使用
__declspec(dllexport) float * voidToFloat(void *data)
{
    float* p=(float *)data; 
    printf("参数\tp1\t值\t= %0.2f\n",*p);
    *p+=3.14;
    printf("参数\tp1\t值\t= %0.2f\n",*p);
    return p;
}
//测试C语言void指针转成 bool 指针的使用
__declspec(dllexport) bool* voidToBool(void *data)
{
    bool* p=(bool *)data; 
    printf("参数\tp1\t值\t= %d\n",*p);
    *p=!*p;
    printf("参数\tp1\t值\t= %d\n",*p);
    return p;
}

//测试C语言指向数组指针的使用
__declspec(dllexport) void cToIntArray1(int *p,int size) {
    printf("开始输出\n");
    for(int i=0;i<size;i++){
        printf("p[%d]=%d\t",i,*(p+i));
    }
    printf("\n修改\n");
    for(int i=0;i<size;i++){
        *(p+i)=*(p+i)*10;
    }
    printf("内容*10 修改结束\n");
}
//测试C语言int数组的使用
__declspec(dllexport) void cToIntArray2(int v[3]) {
    int size=3;
    printf("开始输出\n");
    for(int i=0;i<size;i++){
        printf("v[%d]=%d\t",i,v[i]);
    }
    printf("修改\n");
    for(int i=0;i<size;i++){
        v[i]=v[i]+10;
    }
    printf("内容+10 修改结束\n");
}

__declspec(dllexport) int cToString(char * str){
    unsigned long long len=strlen(str);
    printf("字符串长度%4lld,\t内容是 [%s]\n",len,str);
    printf("开始修改字符,字母大写");
    int count=0;
    for(int i=0;i<len;i++)
    {
        char c=*(str+i);
        if(c>=65 && c<=90 || c>=97 && c<=122){
            count++;
            c=(c | 32) ^ 32;
            *(str+i)=c;
        }
    }
    //printf("\nA=%d,Z=%d,a=%d,z=%d\n",'A','Z','a'^32,'z');
    return count;
}